home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / mg2a_src.zip / KBD.C < prev    next >
C/C++ Source or Header  |  1988-08-23  |  9KB  |  392 lines

  1. /*
  2.  *        Terminal independent keyboard handling.
  3.  */
  4. #include    "def.h"
  5. #include    "kbd.h"
  6.  
  7. #define EXTERN
  8. #include    "key.h"
  9.  
  10. #ifndef NO_MACRO
  11. #include "macro.h"
  12. #endif
  13.  
  14. #ifdef    DO_METAKEY
  15. #ifndef METABIT
  16. #define METABIT 0x80
  17. #endif
  18.  
  19. int use_metakey = TRUE;
  20.  
  21. /*
  22.  * Toggle the value of use_metakey
  23.  */
  24. do_meta(f, n)
  25. {
  26.     if(f & FFARG)    use_metakey = n > 0;
  27.     else        use_metakey = !use_metakey;
  28.     ewprintf("Meta keys %sabled", use_metakey ? "en" : "dis");
  29.     return TRUE;
  30. }
  31. #endif
  32.  
  33. #ifdef    BSMAP
  34. static int bs_map = BSMAP;
  35. /*
  36.  * Toggle backspace mapping
  37.  */
  38. bsmap(f, n)
  39. {
  40.     if(f & FFARG)    bs_map = n > 0;
  41.     else        bs_map = ! bs_map;
  42.     ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
  43.     return TRUE;
  44. }
  45. #endif
  46.  
  47. #ifndef NO_DPROMPT
  48. #define PROMPTL 80
  49.   char    prompt[PROMPTL], *promptp;
  50. #endif
  51.  
  52. static    int    pushed = FALSE;
  53. static    int    pushedc;
  54.  
  55. VOID    ungetkey(c)
  56. int    c;
  57. {
  58. #ifdef    DO_METAKEY
  59.     if(use_metakey && pushed && c==CCHR('[')) pushedc |= METABIT;
  60.     else
  61. #endif
  62.         pushedc = c;
  63.     pushed = TRUE;
  64. }
  65.  
  66. int getkey(flag)
  67. int    flag;
  68. {
  69.     int    c;
  70.     char    *keyname();
  71.  
  72. #ifndef NO_DPROMPT
  73.     if(flag && !pushed) {
  74.         if(prompt[0]!='\0' && ttwait()) {
  75.             ewprintf("%s", prompt);    /* avoid problems with % */
  76.             update();        /* put the cursor back     */
  77.             epresf = KPROMPT;
  78.         }
  79.         if(promptp > prompt) *(promptp-1) = ' ';
  80.     }
  81. #endif
  82.     if(pushed) {
  83.         c = pushedc;
  84.         pushed = FALSE;
  85.     } else    c = getkbd();
  86. #ifdef     BSMAP
  87.     if(bs_map)
  88.         if(c==CCHR('H')) c=CCHR('?');
  89.         else if(c==CCHR('?')) c=CCHR('H');
  90. #endif    
  91. #ifdef    DO_METAKEY
  92.     if(use_metakey && (c&METABIT)) {
  93.         pushedc = c & ~METABIT;
  94.         pushed = TRUE;
  95.         c = CCHR('[');
  96.     }
  97. #endif
  98. #ifndef NO_DPROMPT
  99.     if(flag && promptp < &prompt[PROMPTL - 5]) {
  100.         promptp = keyname(promptp, c);
  101.         *promptp++ = '-';
  102.         *promptp = '\0';
  103.     }
  104. #endif
  105.     return c;
  106. }
  107.  
  108. /*
  109.  * doscan scans a keymap for a keyboard character and returns a pointer
  110.  * to the function associated with that character.  Sets ele to the
  111.  * keymap element the keyboard was found in as a side effect.
  112.  */
  113.  
  114. MAP_ELEMENT *ele;
  115.  
  116. PF    doscan(map, c)
  117. register KEYMAP *map;
  118. register int    c;
  119. {
  120.     register MAP_ELEMENT *elec = &map->map_element[0];    /* local register copy for faster access */
  121.     register MAP_ELEMENT *last = &map->map_element[map->map_num];
  122.  
  123.     while(elec < last && c > elec->k_num) elec++;
  124.     ele = elec;            /* used by prefix and binding code    */
  125.     if(elec >= last || c < elec->k_base)
  126.     return map->map_default;
  127.     return elec->k_funcp[c - elec->k_base];
  128. }
  129.  
  130. doin()
  131. {
  132.     KEYMAP    *curmap;
  133.     PF    funct;
  134.  
  135. #ifndef NO_DPROMPT
  136.     *(promptp = prompt) = '\0';
  137. #endif
  138.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  139.     key.k_count = 0;
  140.     while((funct=doscan(curmap,(key.k_chars[key.k_count++]=getkey(TRUE))))
  141.         == prefix)
  142.     curmap = ele->k_prefmap;
  143. #ifndef NO_MACRO
  144.     if(macrodef && macrocount < MAXMACRO)
  145.     macro[macrocount++].m_funct = funct;
  146. #endif
  147.     return (*funct)(0, 1);
  148. }
  149.  
  150. rescan(f, n)
  151. int f, n;
  152. {
  153.     int c;
  154.     register KEYMAP *curmap;
  155.     int i;
  156.     PF    fp;
  157.     int mode = curbp->b_nmodes;
  158.  
  159.     for(;;) {
  160.     if(ISUPPER(key.k_chars[key.k_count-1])) {
  161.         c = TOLOWER(key.k_chars[key.k_count-1]);
  162.         curmap = curbp->b_modes[mode]->p_map;
  163.         for(i=0; i < key.k_count-1; i++) {
  164.         if((fp=doscan(curmap,(key.k_chars[i]))) != prefix) break;
  165.         curmap = ele->k_prefmap;
  166.         }
  167.         if(fp==prefix) {
  168.         if((fp = doscan(curmap, c)) == prefix)
  169.             while((fp=doscan(curmap,key.k_chars[key.k_count++] =
  170.                 getkey(TRUE))) == prefix)
  171.             curmap = ele->k_prefmap;
  172.         if(fp!=rescan) {
  173. #ifndef NO_MACRO
  174.             if(macrodef && macrocount <= MAXMACRO)
  175.             macro[macrocount-1].m_funct = fp;
  176. #endif
  177.             return (*fp)(f, n);
  178.         }
  179.         }
  180.     }
  181.     /* try previous mode */
  182.     if(--mode < 0) return ABORT;
  183.     curmap = curbp->b_modes[mode]->p_map;
  184.     for(i=0; i < key.k_count; i++) {
  185.         if((fp=doscan(curmap,(key.k_chars[i]))) != prefix) break;
  186.         curmap = ele->k_prefmap;
  187.     }
  188.     if(fp==prefix) {
  189.         while((fp=doscan(curmap,key.k_chars[i++]=getkey(TRUE)))
  190.             == prefix)
  191.         curmap = ele->k_prefmap;
  192.         key.k_count = i;
  193.     }
  194.     if(fp!=rescan && i>=key.k_count-1) {
  195. #ifndef NO_MACRO
  196.         if(macrodef && macrocount <= MAXMACRO)
  197.         macro[macrocount-1].m_funct = fp;
  198. #endif
  199.         return (*fp)(f, n);
  200.     }
  201.     }
  202. }
  203.  
  204. universal_argument(f, n)
  205. int f, n;
  206. {
  207.     int c, nn=4;
  208.     KEYMAP *curmap;
  209.     PF    funct;
  210.  
  211.     if(f&FFUNIV) nn *= n;
  212.     for(;;) {
  213.     key.k_chars[0] = c = getkey(TRUE);
  214.     key.k_count = 1;
  215.     if(c == '-') return negative_argument(f, nn);
  216.     if(c >= '0' && c <= '9') return digit_argument(f, nn);
  217.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  218.     while((funct=doscan(curmap,c)) == prefix) {
  219.         curmap = ele->k_prefmap;
  220.         key.k_chars[key.k_count++] = c = getkey(TRUE);
  221.     }
  222.     if(funct != universal_argument) {
  223. #ifndef NO_MACRO
  224.         if(macrodef && macrocount < MAXMACRO-1) {
  225.         if(f&FFARG) macrocount--;
  226.         macro[macrocount++].m_count = nn;
  227.         macro[macrocount++].m_funct = funct;
  228.         }
  229. #endif
  230.         return (*funct)(FFUNIV, nn);
  231.     }
  232.     nn <<= 2;
  233.     }
  234. }
  235.  
  236. /*ARGSUSED*/
  237. digit_argument(f, n)
  238. int f, n;
  239. {
  240.     int nn, c;
  241.     KEYMAP *curmap;
  242.     PF    funct;
  243.  
  244.     nn = key.k_chars[key.k_count-1] - '0';
  245.     for(;;) {
  246.     c = getkey(TRUE);
  247.     if(c < '0' || c > '9') break;
  248.     nn *= 10;
  249.     nn += c - '0';
  250.     }
  251.     key.k_chars[0] = c;
  252.     key.k_count = 1;
  253.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  254.     while((funct=doscan(curmap,c)) == prefix) {
  255.     curmap = ele->k_prefmap;
  256.     key.k_chars[key.k_count++] = c = getkey(TRUE);
  257.     }
  258. #ifndef NO_MACRO
  259.     if(macrodef && macrocount < MAXMACRO-1) {
  260.     if(f&FFARG) macrocount--;
  261.     else macro[macrocount-1].m_funct = universal_argument;
  262.     macro[macrocount++].m_count = nn;
  263.     macro[macrocount++].m_funct = funct;
  264.     }
  265. #endif
  266.     return (*funct)(FFOTHARG, nn);
  267. }
  268.  
  269. negative_argument(f, n)
  270. int f, n;
  271. {
  272.     int nn = 0, c;
  273.     KEYMAP *curmap;
  274.     PF    funct;
  275.  
  276.     for(;;) {
  277.     c = getkey(TRUE);
  278.     if(c < '0' || c > '9') break;
  279.     nn *= 10;
  280.     nn += c - '0';
  281.     }
  282.     if(nn) nn = -nn;
  283.     else nn = -n;
  284.     key.k_chars[0] = c;
  285.     key.k_count = 1;
  286.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  287.     while((funct=doscan(curmap,c)) == prefix) {
  288.     curmap = ele->k_prefmap;
  289.     key.k_chars[key.k_count++] = c = getkey(TRUE);
  290.     }
  291. #ifndef NO_MACRO
  292.     if(macrodef && macrocount < MAXMACRO-1) {
  293.     if(f&FFARG) macrocount--;
  294.     else macro[macrocount-1].m_funct = universal_argument;
  295.     macro[macrocount++].m_count = nn;
  296.     macro[macrocount++].m_funct = funct;
  297.     }
  298. #endif
  299.     return (*funct)(FFNEGARG, nn);
  300. }
  301.  
  302. /*
  303.  * Insert a character.    While defining a macro, create a "LINE" containing
  304.  * all inserted characters.
  305.  */
  306.  
  307. selfinsert(f, n)
  308. int f, n;
  309. {
  310.     register int c;
  311.     int count;
  312.     VOID lchange();
  313. #ifndef NO_MACRO
  314.     LINE *lp;
  315.     int insert();
  316. #endif
  317.  
  318.     if (n < 0)    return FALSE;
  319.     if (n == 0) return TRUE;
  320.     c = key.k_chars[key.k_count-1];
  321. #ifndef NO_MACRO
  322.     if(macrodef && macrocount < MAXMACRO) {
  323.     if(f & FFARG) macrocount -= 2;
  324.     if(lastflag & CFINS) {    /* last command was insert -- tack on end */
  325.         macrocount--;
  326.         if(maclcur->l_size < maclcur->l_used + n) {
  327.         if((lp = lallocx(maclcur->l_used + n)) == NULL)
  328.             return FALSE;
  329.         lp->l_fp = maclcur->l_fp;
  330.         lp->l_bp = maclcur->l_bp;
  331.         lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
  332.         bcopy(maclcur->l_text, lp->l_text, maclcur->l_used);
  333.         for(count = maclcur->l_used; count < lp->l_used; count++)
  334.             lp->l_text[count] = c;
  335.         free((char *)maclcur);
  336.         maclcur = lp;
  337.         } else {
  338.         maclcur->l_used += n;
  339.         for(count = maclcur->l_used-n; count < maclcur->l_used; count++)
  340.             maclcur->l_text[count] = c;
  341.         }
  342.     } else {
  343.         macro[macrocount-1].m_funct = insert;
  344.         if((lp = lallocx(n)) == NULL) return FALSE;
  345.         lp->l_bp = maclcur;
  346.         lp->l_fp = maclcur->l_fp;
  347.         maclcur->l_fp = lp;
  348.         maclcur = lp;
  349.         for(count = 0; count < n; count++)
  350.         lp->l_text[count] = c;
  351.     }
  352.     thisflag |= CFINS;
  353.     }
  354. #endif
  355.     if(c == '\n') {
  356.     do {
  357.         count = lnewline();
  358.     } while (--n && count==TRUE);
  359.     return count;
  360.     }
  361.     if(curbp->b_flag & BFOVERWRITE) {        /* Overwrite mode    */
  362.     lchange(WFEDIT);
  363.     while(curwp->w_doto < llength(curwp->w_dotp) && n--)
  364.         lputc(curwp->w_dotp, curwp->w_doto++, c);
  365.     if(n<=0) return TRUE;
  366.     }
  367.     return linsert(n, c);
  368. }
  369.  
  370. /*
  371.  * this could be implemented as a keymap with everthing defined
  372.  * as self-insert.
  373.  */
  374. quote(f, n)
  375. {
  376.     register int c;
  377.  
  378.     key.k_count = 1;
  379.     if((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
  380.     key.k_chars[0] -= '0';
  381.     if((c = getkey(TRUE)) >= '0' && c <= '7') {
  382.         key.k_chars[0] <<= 3;
  383.         key.k_chars[0] += c - '0';
  384.         if((c = getkey(TRUE)) >= '0' && c <= '7') {
  385.         key.k_chars[0] <<= 3;
  386.         key.k_chars[0] += c - '0';
  387.         } else ungetkey(c);
  388.     } else ungetkey(c);
  389.     }
  390.     return selfinsert(f, n);
  391. }
  392.